#ifndef ROOM_HPP_INCLUDED
#define ROOM_HPP_INCLUDED
#include "locker.h"
#include "request.hpp"
#include <unordered_map>
#include <math.h>
#include <json/json.h>

using namespace std;

struct roomInfo
{
    roomInfo(const string& _roomNo,bool _isOpen,int _wind,double _temperature,double _currentTemperature)
        :roomNo(_roomNo),
        isOpen(_isOpen),
        wind(_wind),
        temperature(_temperature),
        currentTemperature(_currentTemperature),
        cost(0),
        energy(0) {}
    string roomNo;
    bool isOpen;
    int wind;
    double temperature;
    double currentTemperature;
    double cost;
    double energy;
};

class rooms
{
private:
    unordered_map<string,roomInfo> room;
    rwLock roomLock;
    static double price;
public:
    bool isExist(const string& roomNo)
    {
        roomLock.rLock();
        if(room.find(roomNo)==room.end())
        {
            roomLock.unLock();
            return false;
        }
        roomLock.unLock();
        return true;
    }
    bool insert(const string& roomNo,const roomInfo& rInfo)
    {

        roomLock.wLock();
        room.insert(make_pair(roomNo,rInfo));
        roomLock.unLock();
        return true;

    }
    bool modify(const string& _roomNo,double _temperature,int _wind,bool _isOpen)
    {
        auto iter=room.find(_roomNo);
        roomLock.wLock();
        iter->second.temperature=_temperature;
        iter->second.wind=_wind;
        iter->second.isOpen=_isOpen;
        roomLock.unLock();
        return true;
    }
    bool remove(const string& _roomNo)
    {
        auto iter=room.find(_roomNo);
        roomLock.wLock();
        room.erase(iter);
        roomLock.unLock();
        return true;
    }
    bool charge(const string& _roomNo,double temperature)
    {
        auto iter=room.find(_roomNo);
        roomLock.wLock();
        iter->second.currentTemperature=temperature;
        if(fabs(iter->second.currentTemperature-iter->second.temperature)<0.5)
        {
            iter->second.isOpen=false;
        }
        if(iter->second.isOpen)
        {
            iter->second.energy+=iter->second.wind;
            iter->second.cost=0.5*iter->second.energy;
        }
        roomLock.unLock();
        return true;
    }
    bool feedBack(const string& _roomNo,int _fd){
        auto iter=room.find(_roomNo);
        Json::Value root;
        Json::FastWriter writer;
        Json::Value info;
        info["switch"] = iter->second.isOpen?1:0;
        info["temperature"] = iter->second.temperature;
        info["wind"]=iter->second.wind;
        info["cost"]=iter->second.cost;
        root.append(info);
        string j=writer.write(root);
        cout<<(iter->second.isOpen?1:0)<<" "<<iter->second.temperature<<" "<<iter->second.wind<<" "<<iter->second.cost<<" "<<iter->second.currentTemperature<<endl;
        //sleep(1);
        //send(_fd,j.c_str(),j.size()+1,0);
        return true;
    }
};

#endif // ROOM_HPP_INCLUDED
